home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / ka9q / expiry / command.asm < prev    next >
Encoding:
Assembly Source File  |  1990-05-01  |  13.3 KB  |  619 lines

  1.     .MODEL    MEMMOD,C
  2.     LOCALS
  3.     %MACS
  4.     .LALL
  5.  
  6. comment \
  7.  
  8. To install this into Karn's NET, make the following changes to pc.c, and
  9. add command.obj to the makefile's PCOBJS and pc.tl.  This version works
  10. with "890405 NOS (TurboC large model)".
  11. -russ nelson
  12.  
  13. *** orig/pc.c
  14. --- pc.c
  15. **************
  16. *** 42,47
  17.       char *rp;
  18.       int cnt;
  19.   } Keyboard;
  20.   
  21.   /* Called at startup time to set up console I/O, memory heap */
  22.   ioinit(mem)
  23. --- 42,48 -----
  24.       char *rp;
  25.       int cnt;
  26.   } Keyboard;
  27. + int Nokeys = 0;                /* true if we ignore keystrokes */
  28.   
  29.   /* Called at startup time to set up console I/O, memory heap */
  30.   ioinit(mem)
  31. **************
  32. *** 135,140
  33.       int ret;
  34.   #ifdef __TURBOC__
  35.   
  36.       ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  37.       if((command = getenv("COMSPEC")) == NULLCHAR)
  38.           command = "/COMMAND.COM";
  39. --- 136,149 -----
  40.       int ret;
  41.   #ifdef __TURBOC__
  42.   
  43. +     if (!start_back())
  44. +         return -1;
  45. +     Nokeys++;
  46.       ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20);  /* put stdout in cooked mode */
  47.       if((command = getenv("COMSPEC")) == NULLCHAR)
  48.           command = "/COMMAND.COM";
  49. **************
  50. *** 141,146
  51.       ret = spawnv(P_WAIT,command,argv);
  52.   
  53.       ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  54.       return ret;
  55.   #else
  56.       struct sgttyb ttybuf,ttysav;
  57. --- 150,161 -----
  58.       ret = spawnv(P_WAIT,command,argv);
  59.   
  60.       ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20);  /* put stdout in raw mode */
  61. +     Nokeys--;
  62. +     stop_back();
  63.       return ret;
  64.   #else
  65.       struct sgttyb ttybuf,ttysav;
  66. **************
  67. *** 168,173
  68.       int sig = 0;
  69.       int c;
  70.   
  71.       while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
  72.           sig = 1;
  73.           *Keyboard.wp++ = c;
  74. --- 190,197 -----
  75.       int sig = 0;
  76.       int c;
  77.   
  78. +     if (Nokeys)
  79. +         return;
  80.       while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
  81.           sig = 1;
  82.           *Keyboard.wp++ = c;
  83. \
  84.  
  85. ;    extrn    extern_call: far
  86.     extrn    pwait: far
  87.  
  88.     .DATA
  89.     db    4096 dup(?)
  90. stack    label    byte
  91.  
  92.  
  93.     .CODE
  94.  
  95. dbase    dw    @Data
  96.  
  97. segoff    struc
  98. offs    dw    ?
  99. segm    dw    ?
  100. segoff    ends
  101.  
  102. main_subr    dw    ?
  103.  
  104. their_8h    dd ?
  105. their_10h    dd ?
  106. their_13h    dd ?
  107. their_1Bh    dd ?
  108. their_21h    dd ?
  109. their_23h    dd ?
  110. their_24h    dd ?
  111. their_28h    dd ?
  112. their_2fh    dd ?
  113.  
  114. dos_segment    dw ?            ;segment of internal DOS flags
  115. indos_offset    dw ?            ;offset of INDOS flag
  116. errflag_offset    dw ?            ;offset of critical error flag
  117. program_status    db 0            ;popup status
  118. flag_10h    db 0            ;status of interrupt 10h
  119. flag_13h    db 0            ;status of interrupt 13h
  120. zflag        db ?            ;save and restore critical error.
  121. dos_version    db ?            ;dos major version.
  122. main_countdown    db 20
  123. ss_register    dw ?            ;SS register storage
  124. sp_register    dw ?            ;SP register storage
  125. my_psp        dw ?            ;our PSP.
  126. their_psp        dw ?            ;PSP segment storage
  127.  
  128. tick_counter    dw ?
  129. indos_counter    dw ?
  130. errflag_counter    dw ?
  131. status_counter    dw ?
  132. bp_counter    dw ?
  133. main_counter    dw ?
  134.  
  135.  
  136. their_dta    dd    ?
  137. ;
  138. ;------------------------------------------------------------------------------
  139. ;Interrupt 8 handling routine.
  140. ;------------------------------------------------------------------------------
  141. timer:
  142.     pushf                ;call BIOS routine
  143.     call their_8h
  144.     inc tick_counter
  145.     cmp program_status,0        ;are we already running?
  146.     jne timer_status        ;yes, then suspend ticking.
  147.     cmp flag_10h,0            ;video flag set?
  148.     jne timer_exit            ;yes, then exit
  149.     cmp flag_13h,0            ;disk flag set?
  150.     jne timer_exit            ;yes, then exit
  151.     push es                ;save ES and DI
  152.     push di
  153.     mov es,dos_segment        ;check INDOS flag
  154.     mov di,indos_offset
  155.     cmp byte ptr es:[di],0
  156.     jne timer_indos            ;exit if it's set
  157.     mov di,errflag_offset        ;check critical error flag
  158.     cmp byte ptr es:[di],0
  159.     jne timer_errflag        ;exit if it's set
  160.     mov main_subr,offset cycle
  161.     call main            ;call body of program
  162.     pop di
  163.     pop es
  164. timer_exit:
  165.     iret
  166. timer_indos:
  167.     inc indos_counter
  168.     pop di                ;restore registers
  169.     pop es
  170.     iret
  171. timer_errflag:
  172.     inc errflag_counter
  173.     pop di                ;restore registers
  174.     pop es
  175.     iret
  176. timer_status:
  177.     inc status_counter
  178.     iret
  179.  
  180. ;
  181. ;------------------------------------------------------------------------------
  182. ;Interrupt 10h handling routine.
  183. ;------------------------------------------------------------------------------
  184. video:
  185.     pushf                ;push flags onto stack
  186.     inc flag_10h            ;increment flag
  187.     call their_10h            ;call BIOS routine
  188.     dec flag_10h            ;decrement flag
  189.     iret
  190.  
  191. ;
  192. ;------------------------------------------------------------------------------
  193. ;Interrupt 13h handling routine.
  194. ;------------------------------------------------------------------------------
  195. my_13:
  196.     pushf                ;push flags onto stack
  197.     inc flag_13h            ;set 'busy' flag
  198.     call their_13h            ;call BIOS routine
  199.     pushf                ;save output flags
  200.     dec flag_13h            ;clear flag
  201.     popf                ;restore output flags
  202.     retf    2            ;exit without destroying flags
  203.  
  204. ;
  205. ;------------------------------------------------------------------------------
  206. ;Interrupt 2fh handling routine.
  207. ;------------------------------------------------------------------------------
  208. my_2f:
  209.     cmp    ah,0a9h            ;is this our 2f number?
  210.     jne    my_2f_1
  211.     cmp    al,0            ;get installed state?
  212.     jne    my_2f_2
  213.     mov    al,-1            ;yes - return "installed".
  214.     iret
  215. my_2f_2:
  216.     mov    main_subr,offset external_call
  217.     call    main
  218.     iret
  219. my_2f_1:
  220.     jmp    their_2fh
  221.  
  222.  
  223. ;
  224. ;------------------------------------------------------------------------------
  225. ;Interrupt 28h handling routine.
  226. ;------------------------------------------------------------------------------
  227. my_28:
  228.     pushf                ;call original routine
  229.     call their_28h
  230.     inc bp_counter
  231.     cmp program_status,0        ;are we already running?
  232.     jne bp_exit            ;yes, don't enter it again.
  233.     cmp flag_10h,0            ;video flag set?
  234.     jne bp_exit            ;yes, then exit
  235.     cmp flag_13h,0            ;disk flag set?
  236.     jne bp_exit            ;yes, then exit
  237.     push es                ;save ES and DI
  238.     push di
  239.     mov es,dos_segment        ;check critical error flag
  240.     mov di,errflag_offset
  241.     cmp byte ptr es:[di],0
  242.     pop di                ;clean up the stack
  243.     pop es
  244.     jne bp_errflag
  245.     mov main_subr,offset cycle
  246.     call main            ;call main routine
  247. bp_exit:
  248.     iret                ;done - exit
  249. bp_errflag:
  250.     inc errflag_counter
  251.     iret                ;done - exit
  252.  
  253. ;
  254. ;------------------------------------------------------------------------------
  255. ;Interrupt 21h handling routine.
  256. ;------------------------------------------------------------------------------
  257. my_21:
  258.     pushf                ;save the flags
  259.     or    ah,ah            ;Doing function zero?
  260.     je    jump_to_dos        ;If yes, take the jump
  261.     cmp    ah,4bh            ;Doing EXEC function?
  262.     je    jump_to_dos        ;If yes, take the jump
  263.     popf
  264.  
  265.     pushf
  266.     call    cs:their_21h        ;Do the DOS function
  267.  
  268.     pushf                ;Save the result flags
  269.     cmp    cs:program_status,0    ;are we already running?
  270.     jne    no_recursion        ;yes, don't recurse.
  271.     dec    cs:main_countdown
  272.     jne    no_recursion
  273.     mov    cs:main_countdown,20
  274.     mov    main_subr,offset cycle
  275.     call    main            ;Safe to access disk now
  276. no_recursion:
  277.     popf                ;Recover DOS result flags
  278.  
  279.     sti                ;Must return with interrupts on
  280.     retf    2            ;Return with DOS result flags
  281. jump_to_dos:
  282.     popf
  283.     jmp     cs:their_21h
  284.  
  285. ;
  286. ;------------------------------------------------------------------------------
  287. ;Interrupt 24h handling routine (DOS 3.X only).
  288. ;------------------------------------------------------------------------------
  289. my_24:
  290.     mov al,3            ;fail the call in progress
  291. ioexit:
  292.     iret                ;give control back to DOS
  293.  
  294.  
  295. external_call:
  296. ;    call    extern_call
  297.     ret
  298.  
  299.  
  300. cycle:
  301.     xor    ax,ax            ;push a null pointer.
  302.     push    ax
  303.     push    ax
  304.     call    pwait
  305.     add    sp,4
  306.     ret
  307.  
  308. ;
  309. ;------------------------------------------------------------------------------
  310. ;MAIN is the routine called periodically.
  311. ;------------------------------------------------------------------------------
  312. main:
  313.     inc main_counter
  314.     mov program_status,1        ;set program active flag
  315.     cli                ;make sure interrupts are off
  316.     mov ss_register,ss        ;save stack registers
  317.     mov sp_register,sp
  318.     mov ss,cs:dbase            ; establish interrupt data segment
  319.     mov sp,offset stack
  320.     sti                ;enable interrupts
  321.     push ax
  322.     push bx
  323.     push cx
  324.     push dx
  325.     push si
  326.     push di
  327.     push ds
  328.     push es
  329.     push bp
  330. ;
  331. ;Set DS and ES segment registers.
  332. ;
  333.     push cs                ;set DS to code segment
  334.     pop ds
  335.     assume    ds:seg dos_version
  336. ;
  337. ;Save the current active PSP address and activate this PSP.
  338. ;
  339.     mov zflag,0            ;clear flag
  340.     cmp dos_version,2        ;DOS version 2.X?
  341.     jne main5
  342.     mov es,dos_segment        ;point ES:DI to INDOS
  343.     mov di,indos_offset
  344.     cmp byte ptr es:[di],0        ;INDOS clear?
  345.     je main5            ;yes, then branch
  346.     mov di,errflag_offset        ;point ES:DI to error flag
  347.     cmp byte ptr es:[di],0        ;critical error flag clear?
  348.     jne main5            ;no, then branch
  349.     mov byte ptr es:[di],1        ;set critical error flag manually
  350.     mov zflag,1            ;set change flag
  351. main5:
  352.     mov ah,51h            ;get current PSP segment
  353.     int 21h
  354.     mov their_psp,bx            ;save it
  355.  
  356.     mov ah,50h            ;make this the active PSP
  357.     mov bx,my_psp
  358.     int 21h
  359.  
  360.     cmp zflag,0            ;ZFLAG clear?
  361.     je main6            ;yes, then branch
  362.     mov di,errflag_offset        ;point ES:DI to error flag
  363.     mov byte ptr es:[di],0        ;restore error flag value
  364. main6:
  365. ;
  366. ;Reset the interrupt 1Bh, 23h, and 24h vectors.
  367. ;
  368.     call ioset            ;reset interrupt vectors
  369. ;
  370. ;Save the current dta and subdirectory
  371. ;
  372.     mov    ah,2fh            ;get disk transfer address
  373.     int    21h
  374.     mov    their_dta.segm,es
  375.     mov    their_dta.offs,bx
  376.  
  377. ;
  378. ;Call the commutator loop of net until nothing gets queued up.
  379. ;
  380.     mov    ds,cs:dbase    ; establish interrupt data segment
  381.     assume    ds:nothing
  382.     call    main_subr
  383. ;
  384. ;Restore the current dta and subdirectory
  385. ;
  386.     lds    dx,their_dta
  387.     mov    ah,1ah
  388.     int    21h
  389.  
  390. ;
  391. ;Restore interrupt vectors and former active PSP.
  392. ;
  393.     mov ah,50h            ;restore active PSP label
  394.     mov bx,their_psp
  395.     int 21h
  396.     call ioreset            ;restore interrupt vectors
  397. ;
  398. ;Restore registers and stack before exit.
  399. ;
  400.     pop bp                ;restore registers and exit
  401.     pop es
  402.     pop ds
  403.     pop di
  404.     pop si
  405.     pop dx
  406.     pop cx
  407.     pop bx
  408.     pop ax
  409.     cli                ;interrupts off
  410.     mov ss,ss_register        ;switch to original stack
  411.     mov sp,sp_register
  412.     sti                ;interrupts on
  413.     mov program_status,0        ;clear status flag
  414.     ret
  415.  
  416. ;
  417.  
  418. intset:
  419. ;enter with al = interrupt number, cs:dx = offset of new interrupt,
  420. ;    cs:di -> place to store old interrupt.
  421.  
  422.     push    es            ;get the old interrupt into es:bx
  423.     push    ds            ;now set the new interrupt to ds:dx.
  424.     mov    bx,cs
  425.     mov    ds,bx
  426.  
  427.     mov    ah,35h
  428.     int    21h
  429.     mov    [di].segm,es        ;and store it into ds:di.
  430.     mov    [di].offs,bx
  431.  
  432.     mov    ah,25h
  433.     int    21h
  434.  
  435.     pop    ds
  436.     pop    es
  437.  
  438.     ret
  439.  
  440.  
  441. intreset:
  442. ;enter with al = interrupt number, di -> old interrupt.
  443.     push    ds
  444.     mov    ah,25h
  445.     lds    dx,cs:[di]
  446.     int    21h
  447.     pop    ds
  448.     ret
  449.  
  450.  
  451. ;------------------------------------------------------------------------------
  452. ;IOSET vectors interrupts 1Bh, 23h and 24h to internal handlers.  IORESET
  453. ;restores the original vector values.
  454. ;------------------------------------------------------------------------------
  455. ioset:
  456.     mov    al,1bh
  457.     mov    di,offset their_1Bh
  458.     mov    dx,offset ioexit
  459.     call    intset
  460.  
  461.     mov    al,23h
  462.     mov    di,offset their_23h
  463.     mov    dx,offset ioexit
  464.     call    intset
  465.  
  466.     mov    al,24h
  467.     mov    di,offset their_24h
  468.     mov    dx,offset my_24
  469.     call    intset
  470.  
  471.     ret
  472.  
  473. ;
  474. ioreset:
  475.     mov    al,24h
  476.     mov    di,offset their_24h
  477.     call    intreset
  478.  
  479.     mov    al,23h
  480.     mov    di,offset their_23h
  481.     call    intreset
  482.  
  483.     mov    al,1Bh
  484.     mov    di,offset their_1Bh
  485.     call    intreset
  486.  
  487.     ret
  488.  
  489.  
  490.     public    start_back
  491. start_back    proc
  492. ;
  493. ;Remember our psp.
  494. ;
  495.     mov ah,51h            ;get current PSP segment
  496.     int 21h
  497.     mov my_psp,bx            ;save it
  498.  
  499. ;
  500. ;Determine which version of DOS is running.
  501. ;
  502. init3:
  503.     mov ah,30h            ;DOS function 30h
  504.     int 21h
  505.     mov dos_version,al        ;major version number
  506. ;
  507. ;Get and save the address of the INDOS flag.
  508. ;
  509.     mov ah,34h            ;function 34h
  510.     int 21h                ;get address
  511.     mov dos_segment,es        ;save segment
  512.     mov indos_offset,bx        ;save offset
  513. ;
  514. ;Get and save the address of the critical error flag.
  515. ;
  516.     mov ax,3E80h            ;CMP opcode
  517.     mov cx,2000h            ;max search length
  518.     mov di,bx            ;start at INDOS address
  519. init4:
  520.     repne scasw            ;do the search
  521.     jcxz init5            ;branch if search failed
  522.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  523.     je found            ;branch if it is
  524.     jmp init4            ;resume loop if it's not
  525. init5:
  526.     mov cx,2000h            ;search again
  527.     inc bx                ;search odd addresses this time
  528.     mov di,bx
  529. init6:
  530.     repne scasw            ;look for the opcode
  531.     jcxz notfound            ;not found if loop expires
  532.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  533.     je found
  534.     jmp init6
  535. notfound:
  536.     xor    ax,ax
  537.     ret
  538. found:
  539.     mov ax,es:[di]            ;get flag offset address
  540.     mov errflag_offset,ax        ;save it
  541.  
  542. ;
  543. ;Save and replace all required interrupt vectors.
  544. ;
  545.     mov    al,08h
  546.     mov    dx,offset timer
  547.     mov    di,offset their_8h
  548.     call    intset
  549.  
  550.     mov    al,10h
  551.     mov    dx,offset video
  552.     mov    di,offset their_10h
  553.     call    intset
  554.  
  555.     mov    al,13h
  556.     mov    dx,offset my_13
  557.     mov    di,offset their_13h
  558.     call    intset
  559.  
  560.     mov    al,28h
  561.     mov    dx,offset my_28
  562.     mov    di,offset their_28h
  563.     call    intset
  564.  
  565.     mov    al,2fh
  566.     mov    dx,offset my_2f
  567.     mov    di,offset their_2fh
  568.     call    intset
  569.  
  570.     mov    al,21h
  571.     mov    dx,offset my_21
  572.     mov    di,offset their_21h
  573.     call    intset
  574.  
  575.     mov    ax,1
  576.     ret
  577. start_back    endp
  578.  
  579.     public    stop_back
  580. stop_back    proc
  581.     mov    cs:program_status,1
  582.  
  583.     mov    al,08h
  584.     mov    di,offset their_8h
  585.     call    intreset
  586.  
  587.     mov    al,10h
  588.     mov    di,offset their_10h
  589.     call    intreset
  590.  
  591.     mov    al,13h
  592.     mov    di,offset their_13h
  593.     call    intreset
  594.  
  595.     mov    al,28h
  596.     mov    di,offset their_28h
  597.     call    intreset
  598.  
  599.     mov    al,2fh
  600.     mov    di,offset their_2fh
  601.     call    intreset
  602.  
  603.     mov    al,21h
  604.     mov    di,offset their_21h
  605.     call    intreset
  606.  
  607.     mov    cs:program_status,0
  608.  
  609.     mov dx,ds
  610.     mov ax,offset tick_counter
  611.     ret
  612. stop_back    endp
  613.  
  614.     end
  615.